package org.wenhua.yuan.socket_client

import android.os.Handler
import android.util.Log
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
import java.io.*
import java.net.Socket
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/** SocketClient 客户端*/
object SocketClient2 {
    private val TAG = SocketClient2::class.java.simpleName
    private var socket: Socket? = null
    private lateinit var clientCallback: ClientCallback
    private const val SOCKET_PORT = 10000
    // 客户端线程池
    private var clientThreadPool: ExecutorService? = null
    //心跳发送间隔
    private const val HEART_SOMETIME = 3 * 1000

    private var bufferIn: BufferedReader? = null
    private var printWriter: PrintWriter? = null
    private var receiveMsg:String? = null
    private val mHandler: Handler = Handler()

    /** 连接服务 */
    fun connectSocketServer(ipAddress: String, callback: ClientCallback) {
        clientCallback = callback
        Thread {
            try {
                Log.d("客户端执行连接服务端 ", "开始执行：连接${ipAddress}:${SOCKET_PORT}")
                socket = Socket(ipAddress, SOCKET_PORT)
                socket!!.soTimeout = 60000;
                Log.d("客户端执行连接服务端 ", "连接成功！！！${ipAddress}:${SOCKET_PORT}")
                //开启心跳,每隔3秒钟发送一次心跳
                mHandler.post(mHeartRunnable)
                ClientThread(socket!!, clientCallback).start()
            } catch (e: IOException) {
                Log.e("客户端执行连接服务端-异常报错", e.toString())
                e.printStackTrace()
            }
        }.start()
    }

    /** 关闭与服务器的连接 */
    fun closeConnect() {
        bufferIn?.close()
        printWriter?.close()
        socket?.close()
        //关闭线程池
        clientThreadPool?.shutdownNow()
        clientThreadPool = null
    }

    /**
     * 发送数据至服务器
     * @param message 要发送至服务器的字符串
     */
    fun sendToServer(message: String) {
        if (clientThreadPool == null) {
            clientThreadPool = Executors.newSingleThreadExecutor()
        }
        clientThreadPool?.execute {
            if (socket == null) {
                clientCallback.onWarmClientTip("client温馨提示：客户端还未连接")
                return@execute
            }
            if (socket!!.isClosed) {
                clientCallback.onWarmClientTip("client温馨提示：Socket已关闭")
                return@execute
            }
            try {
                printWriter!!.println(message)
            } catch (e: IOException) {
                e.printStackTrace()
                clientCallback.onWarmClientTip("client温馨提示：向服务端发送消息{$message}失败")
            }
        }
    }

    private val mHeartRunnable = Runnable { sendHeartbeat() }

    /**
     * 发送心跳消息
     */
    private fun sendHeartbeat() {
        if (clientThreadPool == null) {
            clientThreadPool = Executors.newSingleThreadExecutor()
        }
        val heartMessage = "=== 客户端已向服务端建立连接，正在发送心跳，收到请回复 ==="
        clientThreadPool?.execute {
            if (socket == null) {
                clientCallback.onWarmClientTip("client温馨提示：客户端还未连接")
                return@execute
            }
            if (socket!!.isClosed) {
                clientCallback.onWarmClientTip("client温馨提示：Socket已关闭")
                return@execute
            }
            try {
                printWriter!!.println(heartMessage) // 向服务端发送心跳信息
                //发送成功以后，重新建立一个心跳消息
                mHandler.postDelayed(mHeartRunnable, HEART_SOMETIME.toLong())
                Log.i(TAG, heartMessage)
            } catch (e: IOException) {
                e.printStackTrace()
                clientCallback.onWarmClientTip("client温馨提示：向服务端发送消息${heartMessage}失败")
            }
        }
    }

    class ClientThread(private val socket: Socket, private val clientCallback: ClientCallback) : Thread() {
        init {
            try {
                printWriter = PrintWriter(
                    BufferedWriter(
                        OutputStreamWriter(
                            socket.getOutputStream(),
                            "UTF-8"
                        )
                    ), true
                )
                bufferIn = BufferedReader(InputStreamReader(socket.getInputStream(), "UTF-8"))
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }
        override fun run() {
            try {
                while (true) {
                    if (bufferIn!!.readLine().also { receiveMsg = it } != null) {
                        Log.d(TAG, "客户端receiveMsg:$receiveMsg")
                        when (receiveMsg) {
                            "[回复心跳消息：服务端，已收到！！！]" -> clientCallback.onHeartbeatServerMessage("[针对服务端心跳回复]\n客户端说，好的！已收到服务端心跳回复")
                            else -> runOnUiThread(Runnable {
                                clientCallback.onReceiveServerMessage(socket.inetAddress.hostAddress, receiveMsg)
                            })
                        }
                    }
                }
            } catch (e: IOException) {
                Log.e(TAG, "receiveMsg: ")
                e.printStackTrace()
            }

        }
    }

}